import 'dart:convert';
import 'dart:ui';

import 'package:t3_data_service/biz_data_source/map/address/poi_search/model/poi_model.dart';
import 'package:t3_data_service/data_provider/live_location/t3_live_location_provider.dart';
import 'package:t3_data_service/data_provider/map_sctx/t3_map_sctx_provider.dart';
import 'package:t3_data_service/t3_data_service.dart';
import 'package:t3_foundation/t3_foundation.dart';
import 'package:t3_map/address_select.dart';
import 'package:t3_map/poi_search/view_model/poi_search_cell_view_model.dart';
import 'package:t3_track/t3_track.dart';

import '../configs/poi_search_base_config.dart';
import '../poi_search/model/section_model.dart';

class SearchPOITracker {
  final POISearchBaseConfig searchConfig;
  SearchPOITracker(this.searchConfig);

  /// 页面曝光
  void pageExposure(bool isFromBackground, String event, List<POIListSection> list) {
    var choosingSpot = searchConfig.isStartPoint ? "出发地" : "目的地";
    var home = CommonAddressService.instance.value(AddressSetupType.home)?.addressTitle ?? '';
    var company = CommonAddressService.instance.value(AddressSetupType.company)?.addressTitle ?? '';
    var properties = {
      "choosing_spot": choosingSpot,
      // "referrer_page_name": currentSensorReferrerTitle,
      "is_set_home_address": home.isNotEmpty,
      "is_set_company_address": company.isNotEmpty,
      "home_address": home,
      "company_address": company,
      "repeat": isFromBackground,
      "poi_expose": _getExposurePoiContent(list)
    };
    trackWithUserLocation(event, properties);
  }

  /// 常用地址：曝光
  void exposureCommonAddress(bool hasPOI, bool isHome) {
    if (searchConfig.pageScene == PageScene.mapSelectSearch) {
      switch(searchConfig.pointType) {
        case T3POIType.start:
          if (hasPOI) {
            T3Track.trackEventName(isHome ? '019902100000301' : '019902100000401');
          } else {
            T3Track.trackEventName(isHome ? '019902100000501' : '019902100000601');
          }
          break;
        case T3POIType.via:
          if (hasPOI) {
            T3Track.trackEventName(isHome ? '019903900000301' : '019903900000401');
          } else {
            T3Track.trackEventName(isHome ? '019903900000501' : '019903900000601');
          }
          break;
        case T3POIType.end:
          if (hasPOI) {
            T3Track.trackEventName(isHome ? '019903700000301' : '019903700000401');
          } else {
            T3Track.trackEventName(isHome ? '019903700000501' : '019903700000601');
          }
          break;
      }
      return;
    }

    if (searchConfig.isStartPoint) {
      if (hasPOI) {
        T3Track.trackEventName(isHome ? '019900600000301' : '019900600000401');
      } else {
        T3Track.trackEventName(isHome ? '019900600000501' : '019900600000601');
      }
    } else {
      if (hasPOI) {
        T3Track.trackEventName(isHome ? '019900800000301' : '019900800000401');
      } else {
        T3Track.trackEventName(isHome ? '019900800000501' : '019900800000601');
      }
    }
  }

  /// 常用地址：点击
  void clickCommonAddress(POISearchCellViewModel? vm, bool isHome) {
    if (searchConfig.pageScene == PageScene.mapSelectSearch) {
      switch(searchConfig.pointType) {
        case T3POIType.start:
          if (vm != null) {
            T3Track.trackEventName(isHome ? '019902100000302' : '019902100000402');
          } else {
            T3Track.trackEventName(isHome ? '019902100000502' : '019902100000602');
          }
          break;
        case T3POIType.via:
          if (vm != null) {
            T3Track.trackEventName(isHome ? '019903900000302' : '019903900000402');
          } else {
            T3Track.trackEventName(isHome ? '019903900000502' : '019903900000602');
          }
          break;
        case T3POIType.end:
          if (vm != null) {
            T3Track.trackEventName(isHome ? '019903700000302' : '019903700000402');
          } else {
            T3Track.trackEventName(isHome ? '019903700000502' : '019903700000602');
          }
          break;
      }
      return;
    }

    if (searchConfig.isStartPoint) {
      if (vm != null) {
        T3Track.trackEventName(isHome ? '019900600000302' : '019900600000402');
      } else {
        T3Track.trackEventName(isHome ? '019900600000502' : '019900600000602');
      }
    } else {
      if (vm != null) {
        T3Track.trackEventName(isHome ? '019900800000302' : '019900800000402');
      } else {
        T3Track.trackEventName(isHome ? '019900800000502' : '019900800000602');
      }
    }

    if (vm?.poi != null) {
      var tip = vm!.poi;
      if (searchConfig.isStartPoint) {
        var saProperties = {
          "ext0": tip.location.longitude,
          "ext1": tip.location.latitude,
          "ext2": 1,
          "ext3": PointSourceType.gdSearchPOI.value,
          "ext4": tip.address
        };
        if (isHome) {
          saProperties['type_gis_spm'] = '019901100100802';
          T3Track.trackEventName('Report_GisPoi', params: saProperties, usePrefix: false);
        } else {
          saProperties['type_gis_spm'] = '019901100100902';
          T3Track.trackEventName('Report_GisPoi', params: saProperties, usePrefix: false);
        }
      } else {
        var saProperties = {
          "ext0": tip.location.longitude,
          "ext1": tip.location.latitude,
          "ext2": 2,
          "ext3": PointSourceType.gdSearchPOI.value,
          "ext4": tip.address
        };
        if (isHome) {
          saProperties['type_gis_spm'] = '019900500100902';
          T3Track.trackEventName('Report_GisPoi', params: saProperties, usePrefix: false);
        } else {
          saProperties['type_gis_spm'] = '019900500101002';
          T3Track.trackEventName('Report_GisPoi', params: saProperties, usePrefix: false);
        }
      }
    }
  }

  /// 搜索列表：曝光
  void didExposureSearchResult(T3SearchCondition condition, List<POIListSection> list) {
    if (searchConfig.pageScene == PageScene.mapSelectSearch) {
      if (condition.keyword.isNotNullAndEmpty()) {
        switch(searchConfig.pointType) {
          case T3POIType.start:
            T3Track.trackEventName('019902100000901');
            break;
          case T3POIType.via:
            T3Track.trackEventName('019901000100201');
            break;
          case T3POIType.end:
            T3Track.trackEventName('019900900100301');
            break;
        }
      } else {
        var historyNum = 0;
        var recommendNum = 0;
        for (var item in list) {
          if (item.category == T3POICategory.history) {
            historyNum = item.list.length;
          }
          if (item.category == T3POICategory.recommend) {
            recommendNum = item.list.length;
          }
        }
        switch(searchConfig.pointType) {
          case T3POIType.start:
            T3Track.trackEventName('019902100000801', params: {'address_num' : historyNum});
            T3Track.trackEventName('019902100000901', params: {'address_num' : recommendNum});
            break;
          case T3POIType.via:
            T3Track.trackEventName('019903900000801', params: {'address_num' : historyNum});
            T3Track.trackEventName('019903900000901', params: {'address_num' : recommendNum});
            break;
          case T3POIType.end:
            T3Track.trackEventName('019903700000801', params: {'address_num' : historyNum});
            T3Track.trackEventName('019903700000901', params: {'address_num' : recommendNum});
            break;
        }
      }
      return;
    }
    if (searchConfig.isStartPoint) {
      if (condition.keyword.isNotNullAndEmpty()) {
        var searchResult = list.safeAccess(0)?.list ?? [];

        var pList = _searchResult(condition, null, searchResult);
        T3Track.trackEventName('019900600001101', params: {
          'list' : pList
        });
        _reportConfoundTag(searchResult);
      } else {
        for (var item in list) {
          if (item.category == T3POICategory.history) {
            T3Track.trackEventName('019900600000801', params: {
              'address_num' : item.list.length
            });
          }
          if (item.category == T3POICategory.recommend) {
            T3Track.trackEventName('019900600000901', params: {
              'address_num' : item.list.length
            });
          }
        }
      }
    } else {
      if (condition.keyword.isNotNullAndEmpty()) {
        var searchResult = list.safeAccess(0)?.list ?? [];

        var pList = _searchResult(condition, null, searchResult);
        T3Track.trackEventName('019900800002101', params: {
          'list' : pList
        });
        _reportConfoundTag(searchResult);
      } else {
        for (var item in list) {
          if (item.category == T3POICategory.history) {
            T3Track.trackEventName('019900800000801', params: {
              'address_num' : item.list.length
            });
          }
          if (item.category == T3POICategory.recommend) {
            T3Track.trackEventName('019900800000901', params: {
              'address_num' : item.list.length
            });
          }
        }
      }
    }
  }

  void _reportConfoundTag(List<POISearchCellViewModel> searchResult) {
    if (searchResult.isNotEmpty) {
      var hasConfoundTag = false;
      for (var p in searchResult) {
        var bottoms = p.poi.bottomTags ?? [];
        if (bottoms.isNotEmpty) {
          hasConfoundTag = true;
        }
      }
      if (hasConfoundTag) {
        T3Track.trackExpose("0199.008.000.026");
      }
    }
  }

  /// 搜索列表：点击
  void poiDidClick(
      T3SearchCondition condition,
      POISearchCellViewModel vm,
      List<POIListSection> list) {
    poiDidClick1(condition, vm, list);
    poiDidClick3(condition, vm, list);
    poiDidClick4(condition, vm, list);
    if (searchConfig.pageScene == PageScene.mapSelectSearch) {
      poiDidClick2_2(condition, vm, list);
    } else {
      poiDidClick2_1(condition, vm, list);
    }
  }

  /// 必选
  void poiDidClick1(
      T3SearchCondition condition,
      POISearchCellViewModel vm,
      List<POIListSection> list) {
    if ((vm.poi.bottomTags ?? []).isNotEmpty) {
      T3Track.trackClick("0199.008.000.026");
    }
  }

  void poiDidClick2_1(
      T3SearchCondition condition,
      POISearchCellViewModel vm,
      List<POIListSection> list) {
    if (searchConfig.isStartPoint) {
      if (vm.poi.category == T3POICategory.searchResult) {
        var searchResult = list.safeAccess(0)?.list ?? [];
        var pList = _searchResult(condition, vm.poi.runtimeParams.tableIndex, searchResult);
        T3Track.trackEventName('019900600001102', params: {
          'list' : pList
        });
      } else {
        var params =  {
          "address": vm.poi.address,
          "address_order": (vm.poi.runtimeParams.tableIndex ?? 0),
          "latitude": vm.poi.location.lat,
          "longitude": vm.poi.location.lng,
        };
        if (vm.poi.category == T3POICategory.history) {
          T3Track.trackEventName("019900600000802", params: params);
        }
        if (vm.poi.category == T3POICategory.recommend || vm.poi.category == T3POICategory.guess || vm.poi.category == T3POICategory.enterprise) {
          T3Track.trackEventName("019900600000902", params: params);
        }
      }
    } else {
      if (vm.poi.category == T3POICategory.searchResult) {
        var searchResult = list.safeAccess(0)?.list ?? [];
        var pList = _searchResult(condition, vm.poi.runtimeParams.tableIndex, searchResult);
        T3Track.trackEventName('019900800002102', params: {
          'list' : pList
        });
      } else {
        var params =  {
          "address": vm.poi.address,
          "address_order": (vm.poi.runtimeParams.tableIndex ?? 0),
          "latitude": vm.poi.location.lat,
          "longitude": vm.poi.location.lng,
        };
        if (vm.poi.category == T3POICategory.history) {
          T3Track.trackEventName("019900800000802", params: params);
        }
        if (vm.poi.category == T3POICategory.recommend || vm.poi.category == T3POICategory.guess || vm.poi.category == T3POICategory.enterprise) {
          T3Track.trackEventName("019900800000902", params: params);
        }
      }
    }
  }

  void poiDidClick2_2(
      T3SearchCondition condition,
      POISearchCellViewModel vm,
      List<POIListSection> list) {
    var title = vm.poi.address;
    var order = (vm.poi.runtimeParams.tableIndex ?? 0);
    var lat = vm.poi.location.latitude;
    var lng = vm.poi.location.longitude;
    var info = {
      "address": title,
      "address_order": order,
      "latitude": lat,
      "longitude": lng,
    };

    if (vm.poi.category == T3POICategory.searchResult) {
      switch(searchConfig.pointType) {
        case T3POIType.start:
          T3Track.trackEventName('019902100000702');
          T3Track.trackEventName('019900700100302');
          break;
        case T3POIType.via:
          T3Track.trackEventName('019903900000702');
          T3Track.trackEventName('019900900100302');
          break;
        case T3POIType.end:
          T3Track.trackEventName('019903700000702');
          T3Track.trackEventName('019901000100202');
          break;
      }
    } else if (vm.poi.category == T3POICategory.history) {
      switch(searchConfig.pointType) {
        case T3POIType.start:
          T3Track.trackEventName('019902100000802', params: info);
          break;
        case T3POIType.via:
          T3Track.trackEventName('019903900000802', params: info);
          break;
        case T3POIType.end:
          T3Track.trackEventName('019903700000802', params: info);
          break;
      }
    } else if (vm.poi.category == T3POICategory.recommend) {
      switch(searchConfig.pointType) {
        case T3POIType.start:
          T3Track.trackEventName('019902100000902', params: info);
          break;
        case T3POIType.via:
          T3Track.trackEventName('019903900000902', params: info);
          break;
        case T3POIType.end:
          T3Track.trackEventName('019903700000902', params: info);
          break;
      }
    }
  }

  void poiDidClick3(
      T3SearchCondition condition,
      POISearchCellViewModel vm,
      List<POIListSection> list) {
    Map<String, dynamic> saProperties = {
      "ext0": vm.poi.location.longitude,
      "ext1": vm.poi.location.latitude,
      "ext2": searchConfig.pointType.type
    };
    if (vm.poi.category == T3POICategory.searchResult) {
      if (vm.poi.runtimeParams.poiAction == PoiAction.searchMap) {
        saProperties['ext3'] = PointSourceType.gdSearchPOI.value;
        saProperties['ext4'] = vm.poi.name;
        if (vm.poi.runtimeParams.tableIndex != null) {
          saProperties["ext5"] = vm.poi.runtimeParams.tableIndex;
        }
        if (searchConfig.isStartPoint) {
          saProperties['type_gis_spm'] = '019901100300602';
        } else {
          saProperties['type_gis_spm'] = '019900500300602';
        }
        T3Track.trackEventName('Report_GisPoi', params: saProperties, usePrefix: false);
      }
    } else {
      saProperties['ext3'] = PointSourceType.t3Calculate.value;
      saProperties['ext4'] = vm.poi.name;
      if (vm.poi.runtimeParams.tableIndex != null) {
        saProperties["ext5"] = vm.poi.runtimeParams.tableIndex;
      }
      if (searchConfig.isStartPoint) {
        if (vm.poi.category == T3POICategory.history) {
          saProperties['type_gis_spm'] = '019901100300202';
        } else {
          saProperties['type_gis_spm'] = '019901100300402';
        }
      } else {
        if (vm.poi.category == T3POICategory.history) {
          saProperties['type_gis_spm'] = '019900500300202';
        } else {
          saProperties['type_gis_spm'] = '019900500300402';
        }
      }
      T3Track.trackEventName('Report_GisPoi', params: saProperties, usePrefix: false);
    }
  }

  void poiDidClick4(
      T3SearchCondition condition,
      POISearchCellViewModel vm,
      List<POIListSection> list) {
    var isMapSelect = searchConfig.pageScene == PageScene.mapSelectSearch;
    var startEvent = isMapSelect ? 'AddressDepartureViewClick' : 'AddressDepartureClick';
    var endEvent = isMapSelect ? 'AddressDestinationViewClick' : 'AddressDestinationClick';
    var boxString = _getExposurePoiContent(list);
    var saParams = {
      "position": vm.poi.runtimeParams.tableIndex,
      "history": vm.poi.category == T3POICategory.history,
      "search_content": condition.keyword,
      "poi_content": boxString
    };
    var resultEvent = searchConfig.isStartPoint ? startEvent : endEvent;
    trackWithUserLocation(resultEvent, saParams);
  }

  void poiDidFinishSet(T3SearchCondition condition, POISearchCellViewModel vm,  int halfwayCount) {
    var mapType = T3MapSctxProvider.instance.currentMapType.value - 1;
    var poi = vm.poi;
    var departure_longitude = poi.location.longitude;
    var departure_latitude = poi.location.latitude;
    var departure_name = poi.name;
    if (vm.mapSelectedData != null) {
      var mapPoi = AddressPoi.fromJson(vm.mapSelectedData!);
      departure_latitude = mapPoi.location.latitude;
      departure_longitude = mapPoi.location.longitude;
      departure_name = mapPoi.addressTitle;
    }
    if (departure_name == null || departure_latitude == null || departure_longitude == null) {
      return;
    }

    if (searchConfig.isStartPoint) {
      var properties = {
        "departure_set_way": "手动设置",
        "departure_longitude": departure_longitude,
        "departure_latitude": departure_latitude,
        "departure_name": departure_name,
        "search_result_position": poi.runtimeParams.tableIndex,
        "position": poi.runtimeParams.tableIndex,
        "departure_manual_set_type": poi.runtimeParams.poiAction?.stringValue,
        "search_content": condition.keyword,
        "entrance_page_name": searchConfig.refererPageTitle,
        // "gps_status": T3Location.shared.horizontalAccuracy ?? 0,
        // "net_status": NetPing.shard.value,
        "mapType": mapType
      };
      trackWithUserLocation("DepartureSet", properties);
    } else {
      var properties = {
        "destination_longitude": departure_longitude,
        "destination_latitude": departure_latitude,
        "destination_name": departure_name,
        "is_add_halfway_point": halfwayCount > 0,
        "halfway_point_num": halfwayCount,
        "entrance_page_name": searchConfig.refererPageTitle,
        "search_result_position": poi.runtimeParams.tableIndex,
        "destination_manual_set_type": poi.runtimeParams.poiAction?.stringValue,
        "position": poi.runtimeParams.tableIndex,
        "search_content": condition.keyword,
        // "gps_status": T3Location.shared.horizontalAccuracy ?? 0,
        // "net_status": NetPing.shard.value,
        "mapType": mapType
      };
      trackWithUserLocation("DestinationSet", properties);
    }
  }

  /// 取消按钮
  void clickCancel() {
    if (searchConfig.pageScene == PageScene.mapSelectSearch) {
      switch(searchConfig.pointType) {
        case T3POIType.start:
          T3Track.trackEventName('019902100000202');
          break;
        case T3POIType.via:
          T3Track.trackEventName('019903900000202');
          break;
        case T3POIType.end:
          T3Track.trackEventName('019903700000202');
          break;
      }
      return;
    }

    if (searchConfig.isStartPoint) {
      T3Track.trackEventName("019900600000202");
    } else {
      T3Track.trackEventName("019900800000202");
    }
  }
}

extension SearchPOITrackerInner on SearchPOITracker {
  List<String> _searchResult(T3SearchCondition condition, int? selectedIndex, List<POISearchCellViewModel> searchResult) {
    var index = 1;
    var pList = searchResult.map((e) {
      var model = SpmExposureModel();
      var p = e.poi;
      model.address = p.name;
      model.address_order = p.runtimeParams.tableIndex;
      model.latitude = p.location.latitude;
      model.longitude = p.location.longitude;
      model.search_content = condition.keyword;
      if (p.tagType != null) {
        model.type = p.tagType;
      }
      /// 选中的tableIndex
      if (selectedIndex != null) {
        model.click_type = (selectedIndex == index) ? 1 : 2;
      }
      index += 1;
      var json = model.toJson();
      var str = jsonEncode(json);
      return str;
    }).toList();
    return pList;
  }

  String _getExposurePoiContent(List<POIListSection> list) {
    List<Map<String, dynamic>> box = [];
    if (list.isNotEmpty) {
      for (var section in list) {
        for (var poi in section.list) {
          if (poi.poi.runtimeParams.spmIsExposure == true) {
            var poi_id = section.category == T3POICategory.searchResult ? poi.poi.t3Id : poi.poi.poiId;
            var info = PoiExpose(
              longitude: poi.poi.location.longitude,
              latitude: poi.poi.location.latitude,
              poi_id: poi_id,
            );
            var json = info.toJson();
            box.add(json);
          }
        }
      }
    }
    var str = jsonEncode(box);
    return str;
  }

  void trackWithUserLocation(String event, Map<String, dynamic> properties) {
    var location = T3LiveLocationProvider.instance.liveLocation;
    var params = properties;
    if (location != null) {
      addKeyValue('city', location.city, params);
      addKeyValue('county', location.adCode, params);
      addKeyValue('longitude', location.longitude, params);
      addKeyValue('latitude', location.latitude, params);
    }
    T3Track.trackEventName(event, params: params);
  }

  void addKeyValue(String key, dynamic value, Map<String, dynamic> map) {
    if (map.containsKey(key)) {
      return;
    }
    map[key] = value;
  }
}

class SpmExposureModel {
  String? address;
  int? address_order;
  double? latitude;
  double? longitude;
  int? click_type;
  String? search_content;
  String? type;

  SpmExposureModel({
    this.address,
    this.address_order,
    this.latitude,
    this.longitude,
    this.click_type,
    this.search_content,
    this.type,
  });

  Map<String, dynamic> toJson() {
    return {
      'address': address,
      'address_order': address_order,
      'latitude': latitude,
      'longitude': longitude,
      'click_type': click_type,
      'search_content': search_content,
      'type': type,
    };
  }
}

class PoiExpose {
  String? poi_id;
  int? poi_type;
  double? longitude;
  double? latitude;

  PoiExpose({
    this.poi_id,
    this.poi_type,
    this.longitude,
    this.latitude,
  });

  Map<String, dynamic> toJson() {
    var map = <String, dynamic>{};
    if (poi_id != null) {
      map['poi_id'] = poi_id;
    }
    if (poi_type != null) {
      map['poi_type'] = poi_type;
    }
    if (longitude != null) {
      map['longitude'] = longitude;
    }
    if (latitude != null) {
      map['latitude'] = latitude;
    }
    return map;
  }
}